using SqlQueryBuilder.Queries;
using SqlQueryBuilder.Util;

namespace SqlQueryBuilder.Clauses
{
    /// <summary>
    /// In Clause
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class In<T> : AbstractValueClause, IConditionalClause
    {
        private readonly string field;
        private readonly T[] valueList;
        private readonly IInterrogationQuery selectQuery;

        /// <summary>
        /// Initializes a new instance of the <see cref="In&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="valueList">The value list.</param>
        public In(string field, params T[] valueList)
        {
            this.field = field;
            this.valueList = valueList;
            selectQuery = null;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="In&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="selectQuery">The select query.</param>
        public In(string field, IInterrogationQuery selectQuery)
        {
            this.field = field;
            this.selectQuery = selectQuery;
            valueList = null;
        }

        /// <summary>
        /// Builds the where clause.
        /// </summary>
        /// <returns></returns>
        public string BuildConditionalClause()
        {
            return CreateClause();
        }

        /// <summary>
        /// Creates the clause.
        /// </summary>
        /// <returns></returns>
        private string CreateClause() {
            string inList = string.Empty;
            inList = selectQuery != null ? selectQuery.BuildQuery() : CreateParameterList(inList);
            return string.Format("{0} IN ({1})", field, inList);
        }

        /// <summary>
        /// Creates the parameter list.
        /// </summary>
        /// <param name="inList">The in list.</param>
        /// <returns></returns>
        private string CreateParameterList(string inList) {
            bool firstClause = true;
            foreach (object o in valueList)
            {
                if (firstClause)
                    firstClause = false;
                else
                    inList = SqlMultipleFields.AddSeparator(inList);

                inList += FormatSQLValue(o);
            }
            return inList;
        }
    }
}